// Decompiled on 周六 2月 22 19:31:49 CST 2025 with Zomboid Decompiler v0.1.3 using Vineflower.
package zombie;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.nio.file.DirectoryStream;
import java.nio.file.Files;
import java.nio.file.LinkOption;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import zombie.core.Core;
import zombie.core.Translator;
import zombie.core.logger.ExceptionLogger;
import zombie.debug.DebugLog;
import zombie.gameStates.ChooseGameInfo;
import zombie.iso.IsoWorld;
import zombie.modding.ActiveMods;

public final class MapGroups {
    private final ArrayList<zombie.MapGroups.MapGroup> groups = new ArrayList();
    private final ArrayList<zombie.MapGroups.MapDirectory> realDirectories = new ArrayList();

    private static ArrayList<String> getVanillaMapDirectories(boolean _boolean) {
        ArrayList arrayList = new ArrayList();
        File file = zombie.ZomboidFileSystem.instance.getMediaFile("maps");
        String[] string0 = file.list();
        if (string0 != null) {
            for (int _int = 0; _int < string0.length; _int++) {
                String string1 = string0[_int];
                if (string1.equalsIgnoreCase("challengemaps")) {
                    if (_boolean) {
                        try {
                            DirectoryStream directoryStream = Files.newDirectoryStream(
                                Paths.get(file.getPath(), string1),
                                pathx -> Files.isDirectory(pathx, new LinkOption[0]) && Files.exists(pathx.resolve("map.info"), new LinkOption[0])
                            );

                            try {
                                for (Path path : directoryStream) {
                                    arrayList.add(string1 + "/" + path.getFileName().toString());
                                }
                            } catch (Throwable throwable0) {
                                if (directoryStream != null) {
                                    try {
                                        directoryStream.close();
                                    } catch (Throwable throwable1) {
                                        throwable0.addSuppressed(throwable1);
                                    }
                                }

                                throw throwable0;
                            }

                            if (directoryStream != null) {
                                directoryStream.close();
                            }
                        } catch (Exception exception) {
                        }
                    }
                } else {
                    arrayList.add(string1);
                }
            }
        }

        return arrayList;
    }

    public static String addMissingVanillaDirectories(String mapName) {
        ArrayList arrayList0 = getVanillaMapDirectories(false);
        boolean _boolean = false;
        String[] string0 = mapName.split(";");

        for (String string1 : string0) {
            string1 = string1.trim();
            if (!string1.isEmpty() && arrayList0.contains(string1)) {
                _boolean = true;
                break;
            }
        }

        if (!_boolean) {
            return mapName;
        } else {
            ArrayList arrayList1 = new ArrayList();

            for (String string2 : string0) {
                string2 = string2.trim();
                if (!string2.isEmpty()) {
                    arrayList1.add(string2);
                }
            }

            for (String string3 : arrayList0) {
                if (!arrayList1.contains(string3)) {
                    arrayList1.add(string3);
                }
            }

            String string4 = "";

            for (String string5 : arrayList1) {
                if (!string4.isEmpty()) {
                    string4 = string4 + ";";
                }

                string4 = string4 + string5;
            }

            return string4;
        }
    }

    public void createGroups() {
        this.createGroups(ActiveMods.getById("currentGame"), true);
    }

    public void createGroups(ActiveMods activeMods, boolean includeVanilla) {
        this.createGroups(activeMods, includeVanilla, false);
    }

    public void createGroups(ActiveMods activeMods, boolean includeVanilla, boolean includeChallenges) {
        this.groups.clear();
        this.realDirectories.clear();

        for (String string0 : activeMods.getMods()) {
            ChooseGameInfo.Mod mod = ChooseGameInfo.getAvailableModDetails(string0);
            if (mod != null) {
                File file = new File(mod.getDir() + "/media/maps/");
                if (file.exists()) {
                    String[] string1 = file.list();
                    if (string1 != null) {
                        for (int int0 = 0; int0 < string1.length; int0++) {
                            String string2 = string1[int0];
                            if (string2.equalsIgnoreCase("challengemaps")) {
                                if (includeChallenges) {
                                }
                            } else {
                                this.handleMapDirectory(string2, mod.getDir() + "/media/maps/" + string2);
                            }
                        }
                    }
                }
            }
        }

        if (includeVanilla) {
            ArrayList arrayList0 = getVanillaMapDirectories(includeChallenges);
            String string3 = zombie.ZomboidFileSystem.instance.getMediaPath("maps");

            for (String string4 : arrayList0) {
                this.handleMapDirectory(string4, string3 + File.separator + string4);
            }
        }

        for (zombie.MapGroups.MapDirectory mapDirectory0 : this.realDirectories) {
            ArrayList arrayList1 = new ArrayList();
            this.getDirsRecursively(mapDirectory0, arrayList1);
            zombie.MapGroups.MapGroup mapGroup0 = this.findGroupWithAnyOfTheseDirectories(arrayList1);
            if (mapGroup0 == null) {
                mapGroup0 = new zombie.MapGroups.MapGroup();
                this.groups.add(mapGroup0);
            }

            for (zombie.MapGroups.MapDirectory mapDirectory1 : arrayList1) {
                if (!mapGroup0.hasDirectory(mapDirectory1.name)) {
                    mapGroup0.addDirectory(mapDirectory1);
                }
            }
        }

        for (zombie.MapGroups.MapGroup mapGroup1 : this.groups) {
            mapGroup1.setPriority();
        }

        for (zombie.MapGroups.MapGroup mapGroup2 : this.groups) {
            mapGroup2.setOrder(activeMods);
        }

        if (Core.bDebug) {
            int int1 = 1;

            for (zombie.MapGroups.MapGroup mapGroup3 : this.groups) {
                DebugLog.log("MapGroup " + int1 + "/" + this.groups.size());

                for (zombie.MapGroups.MapDirectory mapDirectory2 : mapGroup3.directories) {
                    DebugLog.log("  " + mapDirectory2.name);
                }

                int1++;
            }

            DebugLog.log("-----");
        }
    }

    private void getDirsRecursively(zombie.MapGroups.MapDirectory mapDirectory0, ArrayList<zombie.MapGroups.MapDirectory> arrayList) {
        if (!arrayList.contains(mapDirectory0)) {
            arrayList.add(mapDirectory0);

            for (String string : mapDirectory0.lotDirs) {
                for (zombie.MapGroups.MapDirectory mapDirectory1 : this.realDirectories) {
                    if (mapDirectory1.name.equals(string)) {
                        this.getDirsRecursively(mapDirectory1, arrayList);
                        break;
                    }
                }
            }
        }
    }

    public int getNumberOfGroups() {
        return this.groups.size();
    }

    public ArrayList<String> getMapDirectoriesInGroup(int groupIndex) {
        if (groupIndex >= 0 && groupIndex < this.groups.size()) {
            ArrayList arrayList = new ArrayList();

            for (zombie.MapGroups.MapDirectory mapDirectory : ((zombie.MapGroups.MapGroup)this.groups.get(groupIndex)).directories) {
                arrayList.add(mapDirectory.name);
            }

            return arrayList;
        } else {
            throw new RuntimeException("invalid MapGroups index " + groupIndex);
        }
    }

    public void setWorld(int groupIndex) {
        ArrayList arrayList = this.getMapDirectoriesInGroup(groupIndex);
        String string = "";

        for (int _int = 0; _int < arrayList.size(); _int++) {
            string = string + (String)arrayList.get(_int);
            if (_int < arrayList.size() - 1) {
                string = string + ";";
            }
        }

        IsoWorld.instance.setMap(string);
    }

    private void handleMapDirectory(String string1, String string0) {
        ArrayList arrayList = this.getLotDirectories(string0);
        if (arrayList != null) {
            zombie.MapGroups.MapDirectory mapDirectory = new zombie.MapGroups.MapDirectory(string1, string0, arrayList);
            this.realDirectories.add(mapDirectory);
        }
    }

    private ArrayList<String> getLotDirectories(String string0) {
        File file = new File(string0 + "/map.info");
        if (!file.exists()) {
            return null;
        } else {
            ArrayList arrayList = new ArrayList();

            try {
                FileReader fileReader = new FileReader(file.getAbsolutePath());

                try {
                    BufferedReader bufferedReader = new BufferedReader(fileReader);

                    String string1;
                    try {
                        while ((string1 = bufferedReader.readLine()) != null) {
                            string1 = string1.trim();
                            if (string1.startsWith("lots=")) {
                                arrayList.add(string1.replace("lots=", "").trim());
                            }
                        }
                    } catch (Throwable throwable0) {
                        try {
                            bufferedReader.close();
                        } catch (Throwable throwable1) {
                            throwable0.addSuppressed(throwable1);
                        }

                        throw throwable0;
                    }

                    bufferedReader.close();
                } catch (Throwable throwable2) {
                    try {
                        fileReader.close();
                    } catch (Throwable throwable3) {
                        throwable2.addSuppressed(throwable3);
                    }

                    throw throwable2;
                }

                fileReader.close();
                return arrayList;
            } catch (Exception exception) {
                ExceptionLogger.logException(exception);
                return null;
            }
        }
    }

    private zombie.MapGroups.MapGroup findGroupWithAnyOfTheseDirectories(ArrayList<zombie.MapGroups.MapDirectory> arrayList) {
        for (zombie.MapGroups.MapGroup mapGroup : this.groups) {
            if (mapGroup.hasAnyOfTheseDirectories(arrayList)) {
                return mapGroup;
            }
        }

        return null;
    }

    public ArrayList<String> getAllMapsInOrder() {
        ArrayList arrayList = new ArrayList();

        for (zombie.MapGroups.MapGroup mapGroup : this.groups) {
            for (zombie.MapGroups.MapDirectory mapDirectory : mapGroup.directories) {
                arrayList.add(mapDirectory.name);
            }
        }

        return arrayList;
    }

    public boolean checkMapConflicts() {
        boolean _boolean = false;

        for (zombie.MapGroups.MapGroup mapGroup : this.groups) {
            _boolean |= mapGroup.checkMapConflicts();
        }

        return _boolean;
    }

    public ArrayList<String> getMapConflicts(String mapName) {
        for (zombie.MapGroups.MapGroup mapGroup : this.groups) {
            zombie.MapGroups.MapDirectory mapDirectory = mapGroup.getDirectoryByName(mapName);
            if (mapDirectory != null) {
                ArrayList arrayList = new ArrayList();
                arrayList.addAll(mapDirectory.conflicts);
                return arrayList;
            }
        }

        return null;
    }

    private class MapDirectory {
        String name;
        String path;
        ArrayList<String> lotDirs = new ArrayList();
        ArrayList<String> conflicts = new ArrayList();

        public MapDirectory(String string0, String string1) {
            this.name = string0;
            this.path = string1;
        }

        public MapDirectory(String string0, String string1, ArrayList<String> arrayList) {
            this.name = string0;
            this.path = string1;
            this.lotDirs.addAll(arrayList);
        }

        public void getLotHeaders(ArrayList<String> arrayList) {
            File file = new File(this.path);
            if (file.isDirectory()) {
                String[] string = file.list();
                if (string != null) {
                    for (int _int = 0; _int < string.length; _int++) {
                        if (string[_int].endsWith(".lotheader")) {
                            arrayList.add(string[_int]);
                        }
                    }
                }
            }
        }
    }

    private class MapGroup {
        private LinkedList<zombie.MapGroups.MapDirectory> directories = new LinkedList();

        void addDirectory(String string0, String string1) {
            assert !this.hasDirectory(string0);

            zombie.MapGroups.MapDirectory mapDirectory = MapGroups.this.new MapDirectory(string0, string1);
            this.directories.add(mapDirectory);
        }

        void addDirectory(String string0, String string1, ArrayList<String> arrayList) {
            assert !this.hasDirectory(string0);

            zombie.MapGroups.MapDirectory mapDirectory = MapGroups.this.new MapDirectory(string0, string1, arrayList);
            this.directories.add(mapDirectory);
        }

        void addDirectory(zombie.MapGroups.MapDirectory mapDirectory) {
            assert !this.hasDirectory(mapDirectory.name);

            this.directories.add(mapDirectory);
        }

        zombie.MapGroups.MapDirectory getDirectoryByName(String string) {
            for (zombie.MapGroups.MapDirectory mapDirectory : this.directories) {
                if (mapDirectory.name.equals(string)) {
                    return mapDirectory;
                }
            }

            return null;
        }

        boolean hasDirectory(String string) {
            return this.getDirectoryByName(string) != null;
        }

        boolean hasAnyOfTheseDirectories(ArrayList<zombie.MapGroups.MapDirectory> arrayList) {
            for (zombie.MapGroups.MapDirectory mapDirectory : arrayList) {
                if (this.directories.contains(mapDirectory)) {
                    return true;
                }
            }

            return false;
        }

        boolean isReferencedByOtherMaps(zombie.MapGroups.MapDirectory mapDirectory1) {
            for (zombie.MapGroups.MapDirectory mapDirectory0 : this.directories) {
                if (mapDirectory1 != mapDirectory0 && mapDirectory0.lotDirs.contains(mapDirectory1.name)) {
                    return true;
                }
            }

            return false;
        }

        void getDirsRecursively(zombie.MapGroups.MapDirectory mapDirectory0, ArrayList<String> arrayList) {
            if (!arrayList.contains(mapDirectory0.name)) {
                arrayList.add(mapDirectory0.name);

                for (String string : mapDirectory0.lotDirs) {
                    zombie.MapGroups.MapDirectory mapDirectory1 = this.getDirectoryByName(string);
                    if (mapDirectory1 != null) {
                        this.getDirsRecursively(mapDirectory1, arrayList);
                    }
                }
            }
        }

        void setPriority() {
            for (zombie.MapGroups.MapDirectory mapDirectory : new ArrayList(this.directories)) {
                if (!this.isReferencedByOtherMaps(mapDirectory)) {
                    ArrayList arrayList = new ArrayList();
                    this.getDirsRecursively(mapDirectory, arrayList);
                    this.setPriority(arrayList);
                }
            }
        }

        void setPriority(List<String> list) {
            ArrayList arrayList = new ArrayList(list.size());

            for (String string : list) {
                if (this.hasDirectory(string)) {
                    arrayList.add(this.getDirectoryByName(string));
                }
            }

            for (int _int = 0; _int < this.directories.size(); _int++) {
                zombie.MapGroups.MapDirectory mapDirectory = (zombie.MapGroups.MapDirectory)this.directories.get(_int);
                if (list.contains(mapDirectory.name)) {
                    this.directories.set(_int, (zombie.MapGroups.MapDirectory)arrayList.remove(0));
                }
            }
        }

        void setOrder(ActiveMods activeMods) {
            if (!activeMods.getMapOrder().isEmpty()) {
                this.setPriority(activeMods.getMapOrder());
            }
        }

        boolean checkMapConflicts() {
            HashMap hashMap = new HashMap();
            ArrayList arrayList0 = new ArrayList();

            for (zombie.MapGroups.MapDirectory mapDirectory0 : this.directories) {
                mapDirectory0.conflicts.clear();
                arrayList0.clear();
                mapDirectory0.getLotHeaders(arrayList0);

                for (String string0 : arrayList0) {
                    if (!hashMap.containsKey(string0)) {
                        hashMap.put(string0, new ArrayList());
                    }

                    ((ArrayList)hashMap.get(string0)).add(mapDirectory0.name);
                }
            }

            boolean _boolean = false;

            for (String string1 : hashMap.keySet()) {
                ArrayList arrayList1 = (ArrayList)hashMap.get(string1);
                if (arrayList1.size() > 1) {
                    for (int int0 = 0; int0 < arrayList1.size(); int0++) {
                        zombie.MapGroups.MapDirectory mapDirectory1 = this.getDirectoryByName((String)arrayList1.get(int0));

                        for (int int1 = 0; int1 < arrayList1.size(); int1++) {
                            if (int0 != int1) {
                                String string2 = Translator.getText("UI_MapConflict", mapDirectory1.name, arrayList1.get(int1), string1);
                                mapDirectory1.conflicts.add(string2);
                                _boolean = true;
                            }
                        }
                    }
                }
            }

            return _boolean;
        }
    }
}
